package edu.tongji.structureplayer.structure
{
    public class Load extends BaseStructure
    {
        /** 
        * The type of Load can be one of the following:
        * 1. `Moment' (or `M', `m' for short)
        * 2. `Linear' (or `L', `l' for short)
        */
        private var _type:String;
        private var _strength:Number;
        private var _direction:Number;
        private var _startKeyPoint:KeyPoint;
        private var _endKeyPoint:KeyPoint;
        private var _element:Element;
        private var _node:Node;
        
        /**
        * -1: not set
        * 0 : load on Element
        * 1 : load on Node
        */
        private var loadType:int;
        
        /**
        * There are two kinds of load, the load on Node and the load on element.
        * While ActionScript does not support overload, we must specify which
        * type of load is defined by calling the constructor and one function of
        * setKeyPoints, setForce.
        */
        public function Load(name:String, type:String)
        {
            super(name);
            _type = type;
            loadType = -1;
        }
        
        public function setKeyPoints(element:Element, startKeyPoint:KeyPoint, 
                                     endKeyPoint:KeyPoint):void
        {
            _strength = 0;
            _direction = 0;
            _node = null;
            _startKeyPoint = startKeyPoint;
            _endKeyPoint = endKeyPoint;
            _element = element;
            loadType = 0;
        }
        
        public function setForce(node:Node, strength:Number, direction:Number):void
        {
            _startKeyPoint = null;
            _endKeyPoint = null;
            _element = null;
            _strength = strength;
            _direction = direction;
            _node = node;
            loadType = 1;
        }
        
        /**
        * Gets the forces or moments on one single Node or two Nodes of an Element.
        * The return value is an Array with three or six Numbers which stand for
        * Load on one Node and Load on Element respectively.
        * 
        * Array = [F_1x, F_1y, M_1(, F_2x, F_2y, M_2)]
        * 
        * null returned if Error occurs.
        */
        public function getForce():Array
        {
            switch (loadType)
            {
                case 0:
                    return getForceOnElement();
                case 1:
                    return getForceOnNode();
                default:
                    return null;
            }
        }
        
        private function getForceOnElement():Array
        {
            var force:Array = new Array(6);
            return force;
        }
        
        private function getForceOnNode():Array
        {
            var force:Array = new Array(3);
            if (_type=="Moment" || _type=="M" || _type=="m")
            {
                // The _direction property is ignored.
                force[2] = _strength;
            }
            else if (_type=="Linear" || _type=="L" || _type=="l")
            {
                force[0] = _strength*Math.cos(_direction);
                force[1] = _strength*Math.sin(_direction);
            }
            else
            {
                force = null;
            }
            return force;
        }
        
        /**
        * Since a load can added on a Node or an Element without checking whether
        * there is already one load on a Node or an Element, a load can never overlap
        * with another one.
        */
        public function overlap():Boolean
        {
            return false;
        }

        public function get type():String
        {
            return _type;
        }

        public function set type(value:String):void
        {
            _type = value;
        }

        public function get strength():Number
        {
            return _strength;
        }

        public function set strength(value:Number):void
        {
            _strength = value;
        }

        public function get direction():Number
        {
            return _direction;
        }

        public function set direction(value:Number):void
        {
            _direction = value;
        }

        public function get startKeyPoint():KeyPoint
        {
            return _startKeyPoint;
        }

        public function set startKeyPoint(value:KeyPoint):void
        {
            _startKeyPoint = value;
        }

        public function get endKeyPoint():KeyPoint
        {
            return _endKeyPoint;
        }

        public function set endKeyPoint(value:KeyPoint):void
        {
            _endKeyPoint = value;
        }

        public function get element():Element
        {
            return _element;
        }

        public function set element(value:Element):void
        {
            _element = value;
        }

        public function get node():Node
        {
            return _node;
        }

        public function set node(value:Node):void
        {
            _node = value;
        }
        
        public function debugPrint():void
        {
            var info:String = "Load " + name;
            switch (loadType)
            {
                case 0: info = info + "("
                    + (_element==null?null:_element.name) + ", "
                    + (_startKeyPoint==null?null:_startKeyPoint.name) + ", "
                    + (_endKeyPoint==null?null:_endKeyPoint.name) + ", "
                    + _type
                    + ")";break;
                case 1: info = info + "("
                    + (_node==null?null:_node.name) + ", "
                    + _strength + ", "
                    + _direction + ", "
                    + _type
                    + ")";break;
                default: info += "( )";break;
            }
            trace (info);
        }

    }
}